// 引入Node.js的内置模块
const { spawn, spawnSync } = require("child_process");
const { Socket, isIPv4 } = require("net");
const net = require("net");
const WebSocket = require("ws");
const fs = require("fs");
const path = require("path");
const http = require("http");
const https = require("https");
const Traceroute = require('nodejs-traceroute');
const os = require("os");

// 引入process模块的argv0属性，通常用于获取正在执行的脚本名称
import { argv0 } from "process";
// 引入ps-list模块，用于列出当前运行的进程
import psList from "ps-list";

// 初始化变量
let retries = 0;
const proxies = {}; // 用于存储代理信息
const running_sniffer = {}; // 用于存储运行中的嗅探器信息
var set_time = []; // 时间设置数组
var set_next_hour = 12; // 下一次设置的时间，默认为12小时后
var sleep_time = 0; // 休眠时间
var local_socks5_port = 0; // 本地SOCKS5代理端口
var local_socks5_server = undefined; // 本地SOCKS5代理服务器实例
var socks5_socket_table = {}; // SOCKS5代理的socket映射表

// SOCKS5协议中地址类型常量
const ATYP = {
    DOMAINNAME: 3, // 域名地址类型
   IPV4: 1, // IPv4地址类型
   IPV6: 4, // IPv6地址类型
};

// SOCKS5协议中命令类型常量
const COMMANDS = {
    BIND: 2, // 绑定命令
    CONNECT: 1, // 连接命令
    UDP_ASSOCIATE: 3, // UDP关联命令
};

// SOCKS5协议中认证方法类型常量
const AUTH_METHODS = {
    LOGIN_PASS: 2, // 登录密码认证方法
    GSSAPI: 1, // GSSAPI认证方法
    NO_ACCEPTABLE_METHODS: 0xff, // 没有可接受的认证方法
    NO_AUTHENTICATION: 0, // 不需要认证
};

// SOCKS5协议中回复类型常量
const REPLIES = {
    SUCCEEDED: 0, // 成功
    GENERAL_FAILURE: 1, // 一般失败
    CONNECTION_NOT_ALLOWED: 2, // 连接不允许
    NETWORK_UNREACHABLE: 3, // 网络不可达
    HOST_UNREACHABLE: 4, // 主机不可达
    CONNECTION_REFUSED: 5, // 连接被拒绝
    TTL_EXPIRED: 6, // TTL超时
    COMMAND_NOT_SUPPORTED: 7, // 命令不支持
    ADDRESS_TYPE_NOT_SUPPORTED: 8, // 地址类型不支持
};

const VERSION = 5; // SOCKS5协议版本

// SOCKS5协议中认证回复类型常量
const AUTH_REPLIES = {
    GENERAL_FAILURE: 0xff, // 认证失败
    SUCCEEDED: 0, // 认证成功
};

const AUTH_VERSION = 1; // 认证版本

// 从buffer中获取端口号的函数
const getPort = (buffer) => {
    const port = buffer.readInt16BE(buffer.length - 2);
    if (!Number.isInteger(port) || port < 1 || port > 65535) {
        return false;
    }
    return port;
};

// 从buffer中获取IP地址或域名的函数
const getAddress = (buffer) => {
    if (buffer[3] === ATYP.IPV4) {
        const ip = `${buffer[4]}.${buffer[5]}.${buffer[6]}.${buffer[7]}`;
        if (!isIPv4(ip)) return false;
        return ip;
    }
    if (buffer[3] === ATYP.DOMAINNAME) {
        return buffer.toString('utf8', 5, buffer.length - 2);
    }
    return false;
};

// 创建错误的函数，用于在发生错误时返回一个包含远程地址和端口的错误对象
const createError = (message, socketData) => {
    const error = new Error(message);
    error.remoteAddress = socketData.remoteAddress;
    error.remotePort = socketData.remotePort;
    return error;
};

// 处理SOCKS5协议的CONNECT命令，用于建立到目标服务器的TCP连接
function connect(server, socket, buffer, options) {
    // 解析SOCKS5请求中的命令和地址类型
    const cmd = buffer[1]; // 命令码
    const atyp = buffer[3]; // 地址类型
    const host = getAddress(buffer); // 获取目标主机地址
    const port = getPort(buffer); // 获取目标端口
    const { localAddress } = options; // 本地绑定地址

    // 检查SOCKS5版本是否正确
    if (buffer[0] !== VERSION) {
        const error = createError('Wrong socks version in connect.', socket);
        error.bufferMessage = buffer;
        server.emit('error', error);

        const response = Buffer.from([VERSION, REPLIES.GENERAL_FAILURE]);
        socket.end(response);
        return;
    }

    // 检查地址和端口是否有效
    if (!host || !port) {
        const error = createError('Unsupported address.', socket);
        error.bufferMessage = buffer;
        server.emit('error', error);

        const response = Buffer.from([0x05, REPLIES.ADDRESS_TYPE_NOT_SUPPORTED]);
        socket.end(response);
        return;
    }

    // 检查是否支持UDP_ASSOCIATE和BIND命令
    if (cmd !== COMMANDS.CONNECT) {
        const error = createError('Unsupported UDP_ASSOCIATE and BIND connection.', socket);
        error.bufferMessage = buffer;
        server.emit('error', error);

        const response = Buffer.from([0x05, REPLIES.COMMAND_NOT_SUPPORTED]);
        socket.end(response);
        return;
    }

    // 如果存在过滤函数，检查是否允许连接
    if (typeof options.filter === 'function') {
        const result = options.filter(host);
        if (!result) {
            const response = Buffer.from([VERSION, REPLIES.HOST_UNREACHABLE]);
            socket.end(response);
            return;
        }
    }

    // 尝试建立到目标服务器的连接
    var request = undefined;
    try {
        request = net.connect({ host, port, localAddress }, () => {
            // 连接成功后，发送SOCKS5协议的SUCCEEDED响应
            buffer[1] = REPLIES.SUCCEEDED;
            socket.write(buffer, () => {
                request.pipe(socket);
                socket.pipe(request);
            });
        });
    } catch (err) {
        console.log(`socks5 connect Error connecting to ${host}:${port} with error: ${err.message}`);
        return;
    }

    // 监听socket事件，确保在断开时关闭请求连接
    socket.on('end', () => {
        request.destroy();
    });

    socket.on('timeout', () => {
        request.destroy();
    });

    // 监听请求错误事件，以便在出错时关闭连接
    request.on('error', err => {
        console.log(`request.on connect Error: ${err.message}`);
    })

    // 触发'connect'事件，通知服务器客户端已连接
    request.on('connect', () => {
        try {
            server.emit('connect', { addr: host, port });
        } catch (err) {
            console.log(`request.on connect Error: ${err.message}`);
        }
    });

    // 监听数据事件，转发数据
    request.on('data', (data) => {
        server.emit('data', data);
    });

    // 设置请求超时时间
    request.setTimeout(options.timeout || 120000);
    request.on('timeout', () => {
        request.destroy();
    });

    // 监听错误事件，发送错误响应并关闭连接
    request.on('error', (err) => {
        err.addr = host;
        err.atyp = atyp;
        err.port = port;
        server.emit('error', err);

        let response;
        if (err.code === 'EADDRNOTAVAIL') {
            response = Buffer.from([0x05, REPLIES.HOST_UNREACHABLE]);
        } else if (err.code === 'ECONNREFUSED') {
            response = Buffer.from([0x05, REPLIES.CONNECTION_REFUSED]);
        } else {
            response = Buffer.from([0x05, REPLIES.NETWORK_UNREACHABLE]);
        }
        socket.end(response);
        request.destroy();
    });
}
// 处理SOCKS5协议的认证阶段
function authenticate(server, socket, buffer, options) {
    // 解析用户名和密码
    const ulen = 2 + buffer[1]; // 用户名的最后一个字节
    const name = buffer.toString('utf8', 2, ulen);
    const password = buffer.toString('utf8', ulen + 1, buffer.length);

    // 检查SOCKS5版本是否正确
    if (buffer[0] !== AUTH_VERSION) {
        const error = createError('Unsupported authentication version.', socket);
        error.bufferMessage = buffer;
        server.emit('error', error);

        const response = Buffer.from([
            AUTH_VERSION,
            AUTH_REPLIES.GENERAL_FAILURE,
        ]);
        socket.end(response);
        return;
    }
}

    // 调用认证函数，根据用户名和密码进行认证
    const auth = options.authenticate(name, password);